package com.qhx.rtkcloud.ntrip;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.Arrays;
import java.util.concurrent.LinkedBlockingQueue;

import static com.qhx.rtkcloud.ntrip.BaseStationTcpClient.executorService;

public class MoveTcpClientQueue {
    private ServerSocket moveServerSocket;
    private volatile Socket moveSockt;

    //本地存、云端取
    private LinkedBlockingQueue<byte[]> QueueOne;
    //云端存。本地取
    private LinkedBlockingQueue<byte[]> QueueTwo;

    private ServerSocket localServerSocket;
    private Socket localSocket;


    public MoveTcpClientQueue() {
    }

    public MoveTcpClientQueue(ServerSocket moveServerSocket,ServerSocket localServerSocket) {
        this.moveServerSocket = moveServerSocket;
        this.localServerSocket = localServerSocket;
        this.QueueOne = new LinkedBlockingQueue<byte[]>();
        this.QueueTwo = new LinkedBlockingQueue<byte[]>();

        //监听对应的端口
        waitMoveTcpClient(moveServerSocket);
        //waitLocalTcpClient(localServerSocket);
    }


    private void waitMoveTcpClient(ServerSocket moveServerSocket) {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        Socket socket = moveServerSocket.accept();
                        moveSockt = socket;
                        //云端发到移动站
                        cloudTaskFromQueueOne();
                        //移动站发到云端
                        writeMessageFromClouToQueue();
                    } catch (IOException e) {
                        moveSockt = null;
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    private void cloudTaskFromQueueOne() {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                OutputStream outputStream = null;
                try {
                    outputStream = moveSockt.getOutputStream();
                } catch (IOException e) {
                    //关闭云端的连接
                    closeSocket(moveSockt);
                    e.printStackTrace();
                    return;
                }
                while (true){
                    try {
                        //byte[] take = QueueOne.take();
                        byte[] take = QueueTwo.take();
                        System.out.println("云端发到移动站"+new String(take));
                        outputStream.write(take);
                        outputStream.flush();
                    } catch (Exception e) {
                        closeSocket(moveSockt);
                        e.printStackTrace();
                        return;
                    }
                }
            }
        });
    }

    private void waitLocalTcpClient(ServerSocket localServerSocket){
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                while (true){
                    try {
                        Socket socket = localServerSocket.accept();
                        localSocket = socket;
                        //本地发送到云端
                        localStorageToQueueOne();
                        //云端发送到本地
                        readMessageFromQueueToLocal();
                    } catch (IOException e) {
                        localSocket = null;
                        e.printStackTrace();
                    }
                }

            }
        });
    }

    private void localStorageToQueueOne() {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                InputStream inputStream = null;
                try {
                    inputStream = localSocket.getInputStream();
                } catch (IOException e) {
                    closeSocket(localSocket);
                    e.printStackTrace();
                    return;
                }
                byte[] buffer = new byte[10240];
                while (true){
                    try {
                        int read = inputStream.read(buffer);
                        if (read > 0){
                            byte[] bytes = Arrays.copyOfRange(buffer, 0, read);
                            System.out.println("本地发送到云端"+new String(bytes));
                            QueueOne.offer(bytes);
                        }
                    }catch (SocketTimeoutException e){
                    }catch (IOException e) {
                        closeSocket(localSocket);
                        e.printStackTrace();
                        break;
                    }
                }
            }
        });
    }

    private void writeMessageFromClouToQueue() {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                InputStream inputStream = null;
                try {
                    inputStream = moveSockt.getInputStream();
                } catch (IOException e) {
                    closeSocket(moveSockt);
                    e.printStackTrace();
                    return;
                }
                byte[] buffer = new byte[10240];
                while (true){
                    try {
                        int read = inputStream.read(buffer);
                        if (read > 0){
                            byte[] bytes = Arrays.copyOfRange(buffer, 0, read);
                            System.out.println("移动端发到云端"+new String(bytes));
                            QueueTwo.offer(bytes);
                        }
                    } catch (IOException e) {
                        closeSocket(moveSockt);
                        e.printStackTrace();
                        break;
                    }
                }
            }
        });
    }




    private void readMessageFromQueueToLocal() {
        executorService.submit(new Runnable() {
            @Override
            public void run() {
                OutputStream outputStream = null;
                try {
                    outputStream = localSocket.getOutputStream();
                } catch (IOException e) {
                    //关闭云端的连接
                    closeSocket(localSocket);
                    e.printStackTrace();
                    return;
                }
                while (true){
                    try {
                        System.out.println(" QueueTwo.take()");
                        byte[] take = QueueTwo.take();
                        System.out.println("云端发送到本地"+new String(take));
                        outputStream.write(take);
                        outputStream.flush();
                    } catch (Exception e) {
                        e.printStackTrace();
                        break;
                    }
                }
            }
        });
    }

    //关闭云端的连接
    private void closeSocket(Socket socket){
        if (socket != null){
            try {
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }



    public ServerSocket getMoveServerSocket() {
        return moveServerSocket;
    }

    public void setMoveServerSocket(ServerSocket moveServerSocket) {
        this.moveServerSocket = moveServerSocket;
    }

    public Socket getMoveSockt() {
        return moveSockt;
    }

    public void setMoveSockt(Socket moveSockt) {
        this.moveSockt = moveSockt;
    }

    public LinkedBlockingQueue<byte[]> getQueueOne() {
        return QueueOne;
    }

    public void setQueueOne(LinkedBlockingQueue<byte[]> queueOne) {
        QueueOne = queueOne;
    }

    public LinkedBlockingQueue<byte[]> getQueueTwo() {
        return QueueTwo;
    }

    public void setQueueTwo(LinkedBlockingQueue<byte[]> queueTwo) {
        QueueTwo = queueTwo;
    }

    public ServerSocket getLocalServerSocket() {
        return localServerSocket;
    }

    public void setLocalServerSocket(ServerSocket localServerSocket) {
        this.localServerSocket = localServerSocket;
    }

    public Socket getLocalSocket() {
        return localSocket;
    }

    public void setLocalSocket(Socket localSocket) {
        this.localSocket = localSocket;
    }
}
